namespace YXShop.ExcelLite
{
    using System;

    public sealed class ExcelWorksheet
    {
        private CellRange cells;
        private ExcelColumnCollection columns;
        private int defaultColumnWidth;
        private int firstVisibleColumn;
        private int firstVisibleRow;
        internal ushort fitWorksheetHeightToPages;
        internal ushort fitWorksheetWidthToPages;
        internal double footerMargin;
        internal double headerMargin;
        internal HorizontalPageBreakCollection horizontalPageBreaks;
        private MergedCellRanges mergedRanges;
        private string name;
        private NamedRangeCollection namedRanges;
        internal ushort numberOfCopies;
        private bool outlineColumnButtonsRight;
        private bool outlineRowButtonsBelow;
        private int pageBreakViewZoom;
        internal ushort paperSize;
        private ExcelWorksheetCollection parent;
        internal PreservedRecords PreservedWorksheetRecords;
        internal ushort printResolution;
        private bool protectedWorksheet;
        private ExcelRowCollection rows;
        internal int scalingFactor;
        internal SetupOptions setupOptions;
        internal ushort startPageNumber;
        private VerticalPageBreakCollection verticalPageBreaks;
        internal ushort verticalPrintResolution;
        internal WorksheetWindowOptions windowOptions;
        private int zoom;

        internal ExcelWorksheet(string name, ExcelWorksheetCollection parent)
        {
            this.defaultColumnWidth = 0x924;
            this.outlineRowButtonsBelow = true;
            this.outlineColumnButtonsRight = true;
            this.pageBreakViewZoom = 60;
            this.zoom = 100;
            this.windowOptions = WorksheetWindowOptions.ShowGridLines | WorksheetWindowOptions.ShowZeroValues | WorksheetWindowOptions.ShowSheetHeaders | WorksheetWindowOptions.ShowOutlineSymbols | WorksheetWindowOptions.DefaultGridLineColor;
            this.paperSize = 0;
            this.scalingFactor = 0xff;
            this.startPageNumber = 1;
            this.fitWorksheetWidthToPages = 0;
            this.fitWorksheetHeightToPages = 0;
            this.setupOptions = SetupOptions.Landscape;
            this.printResolution = 0;
            this.verticalPrintResolution = 0;
            this.headerMargin = 0.5;
            this.footerMargin = 0.5;
            this.numberOfCopies = 1;
            this.name = name;
            this.parent = parent;
            this.rows = new ExcelRowCollection(this);
            this.columns = new ExcelColumnCollection(this);
            this.mergedRanges = new MergedCellRanges(this);
            this.horizontalPageBreaks = new HorizontalPageBreakCollection();
            this.verticalPageBreaks = new VerticalPageBreakCollection();
        }

        internal ExcelWorksheet(string name, ExcelWorksheetCollection parent, ExcelWorksheet sourceWorksheet)
        {
            this.defaultColumnWidth = 0x924;
            this.outlineRowButtonsBelow = true;
            this.outlineColumnButtonsRight = true;
            this.pageBreakViewZoom = 60;
            this.zoom = 100;
            this.windowOptions = WorksheetWindowOptions.ShowGridLines | WorksheetWindowOptions.ShowZeroValues | WorksheetWindowOptions.ShowSheetHeaders | WorksheetWindowOptions.ShowOutlineSymbols | WorksheetWindowOptions.DefaultGridLineColor;
            this.paperSize = 0;
            this.scalingFactor = 0xff;
            this.startPageNumber = 1;
            this.fitWorksheetWidthToPages = 0;
            this.fitWorksheetHeightToPages = 0;
            this.setupOptions = SetupOptions.Landscape;
            this.printResolution = 0;
            this.verticalPrintResolution = 0;
            this.headerMargin = 0.5;
            this.footerMargin = 0.5;
            this.numberOfCopies = 1;
            this.name = name;
            this.parent = parent;
            this.protectedWorksheet = sourceWorksheet.protectedWorksheet;
            this.rows = new ExcelRowCollection(this, sourceWorksheet.rows);
            this.columns = new ExcelColumnCollection(this, sourceWorksheet.columns);
            this.defaultColumnWidth = sourceWorksheet.defaultColumnWidth;
            this.mergedRanges = new MergedCellRanges(this, sourceWorksheet.mergedRanges);
            this.outlineRowButtonsBelow = sourceWorksheet.outlineRowButtonsBelow;
            this.outlineColumnButtonsRight = sourceWorksheet.outlineColumnButtonsRight;
            if (sourceWorksheet.PreservedWorksheetRecords != null)
            {
                this.PreservedWorksheetRecords = new PreservedRecords(sourceWorksheet.PreservedWorksheetRecords);
            }
            this.windowOptions = (WorksheetWindowOptions) ((short) (sourceWorksheet.windowOptions & ~(WorksheetWindowOptions.SheetVisible | WorksheetWindowOptions.SheetSelected)));
            this.firstVisibleRow = sourceWorksheet.firstVisibleRow;
            this.firstVisibleColumn = sourceWorksheet.firstVisibleColumn;
            this.pageBreakViewZoom = sourceWorksheet.pageBreakViewZoom;
            this.zoom = sourceWorksheet.zoom;
            this.horizontalPageBreaks = new HorizontalPageBreakCollection(sourceWorksheet.horizontalPageBreaks);
            this.verticalPageBreaks = new VerticalPageBreakCollection(sourceWorksheet.verticalPageBreaks);
            this.paperSize = sourceWorksheet.paperSize;
            this.scalingFactor = sourceWorksheet.scalingFactor;
            this.startPageNumber = sourceWorksheet.startPageNumber;
            this.fitWorksheetWidthToPages = sourceWorksheet.fitWorksheetWidthToPages;
            this.fitWorksheetHeightToPages = sourceWorksheet.fitWorksheetHeightToPages;
            this.setupOptions = sourceWorksheet.setupOptions;
            this.printResolution = sourceWorksheet.printResolution;
            this.verticalPrintResolution = sourceWorksheet.verticalPrintResolution;
            this.headerMargin = sourceWorksheet.headerMargin;
            this.footerMargin = sourceWorksheet.footerMargin;
            this.numberOfCopies = sourceWorksheet.numberOfCopies;
            this.namedRanges = new NamedRangeCollection(this, sourceWorksheet.NamedRanges);
        }

        public void Delete()
        {
            this.parent.DeleteInternal(this);
        }

        private bool GetWindowOption(WorksheetWindowOptions option)
        {
            return (((short) (this.windowOptions & option)) != 0);
        }

        public ExcelWorksheet InsertCopy(string destinationWorksheetName, ExcelWorksheet sourceWorksheet)
        {
            return this.parent.InsertCopyInternal(destinationWorksheetName, this.parent.IndexOf(this), sourceWorksheet);
        }

        public ExcelWorksheet InsertEmpty(string worksheetName)
        {
            return this.parent.InsertInternal(worksheetName, this.parent.IndexOf(this));
        }

        private void SetWindowOption(bool val, WorksheetWindowOptions option)
        {
            this.windowOptions = (WorksheetWindowOptions) ((short) (this.windowOptions & ((short) ~option)));
            if (val)
            {
                this.windowOptions = (WorksheetWindowOptions) ((short) (this.windowOptions | option));
            }
        }

        internal int AutomaticPageBreakScalingFactor
        {
            get
            {
                return this.scalingFactor;
            }
            set
            {
                if ((value < 10) || (value > 400))
                {
                    throw new ArgumentOutOfRangeException("value", value, "AutomaticPageBreakScalingFactor must be in range from 10 to 400.");
                }
                this.scalingFactor = value;
            }
        }

        public CellRange Cells
        {
            get
            {
                if (this.cells == null)
                {
                    this.cells = new CellRange(this);
                }
                return this.cells;
            }
        }

        public ExcelColumnCollection Columns
        {
            get
            {
                return this.columns;
            }
        }

        public int DefaultColumnWidth
        {
            get
            {
                return this.defaultColumnWidth;
            }
            set
            {
                this.defaultColumnWidth = value;
            }
        }

        public int FirstVisibleColumn
        {
            get
            {
                return this.firstVisibleColumn;
            }
            set
            {
                this.firstVisibleColumn = value;
            }
        }

        public int FirstVisibleRow
        {
            get
            {
                return this.firstVisibleRow;
            }
            set
            {
                this.firstVisibleRow = value;
            }
        }

        public HorizontalPageBreakCollection HorizontalPageBreaks
        {
            get
            {
                return this.horizontalPageBreaks;
            }
        }

        internal MergedCellRanges MergedRanges
        {
            get
            {
                return this.mergedRanges;
            }
            set
            {
                this.mergedRanges = value;
            }
        }

        public string Name
        {
            get
            {
                return this.name;
            }
            set
            {
                this.parent.ExceptionIfNotUnique(value);
                this.name = value;
            }
        }

        public NamedRangeCollection NamedRanges
        {
            get
            {
                if (this.namedRanges == null)
                {
                    this.namedRanges = new NamedRangeCollection(this);
                }
                return this.namedRanges;
            }
        }

        public bool OutlineColumnButtonsRight
        {
            get
            {
                return this.outlineColumnButtonsRight;
            }
            set
            {
                this.outlineColumnButtonsRight = value;
            }
        }

        public bool OutlineRowButtonsBelow
        {
            get
            {
                return this.outlineRowButtonsBelow;
            }
            set
            {
                this.outlineRowButtonsBelow = value;
            }
        }

        public int PageBreakViewZoom
        {
            get
            {
                return this.pageBreakViewZoom;
            }
            set
            {
                if ((value < 10) || (value > 400))
                {
                    throw new ArgumentOutOfRangeException("value", value, "PageBreakViewZoom must be in range from 10 to 400.");
                }
                this.pageBreakViewZoom = value;
            }
        }

        internal ExcelWorksheetCollection Parent
        {
            get
            {
                return this.parent;
            }
        }

        internal ExcelFile ParentExcelFile
        {
            get
            {
                return this.Parent.Parent;
            }
        }

        public bool Protected
        {
            get
            {
                return this.protectedWorksheet;
            }
            set
            {
                this.protectedWorksheet = value;
            }
        }

        public ExcelRowCollection Rows
        {
            get
            {
                return this.rows;
            }
        }

        public bool ShowColumnsFromRightToLeft
        {
            get
            {
                return this.GetWindowOption(WorksheetWindowOptions.ColumnsFromRightToLeft);
            }
            set
            {
                this.SetWindowOption(value, WorksheetWindowOptions.ColumnsFromRightToLeft);
            }
        }

        public bool ShowFormulas
        {
            get
            {
                return this.GetWindowOption(WorksheetWindowOptions.ShowFormulas);
            }
            set
            {
                this.SetWindowOption(value, WorksheetWindowOptions.ShowFormulas);
            }
        }

        public bool ShowGridLines
        {
            get
            {
                return this.GetWindowOption(WorksheetWindowOptions.ShowGridLines);
            }
            set
            {
                this.SetWindowOption(value, WorksheetWindowOptions.ShowGridLines);
            }
        }

        public bool ShowInPageBreakPreview
        {
            get
            {
                return this.GetWindowOption(WorksheetWindowOptions.ShowInPageBreakPreview);
            }
            set
            {
                this.SetWindowOption(value, WorksheetWindowOptions.ShowInPageBreakPreview);
            }
        }

        public bool ShowOutlineSymbols
        {
            get
            {
                return this.GetWindowOption(WorksheetWindowOptions.ShowOutlineSymbols);
            }
            set
            {
                this.SetWindowOption(value, WorksheetWindowOptions.ShowOutlineSymbols);
            }
        }

        public bool ShowSheetHeaders
        {
            get
            {
                return this.GetWindowOption(WorksheetWindowOptions.ShowSheetHeaders);
            }
            set
            {
                this.SetWindowOption(value, WorksheetWindowOptions.ShowSheetHeaders);
            }
        }

        public bool ShowZeroValues
        {
            get
            {
                return this.GetWindowOption(WorksheetWindowOptions.ShowZeroValues);
            }
            set
            {
                this.SetWindowOption(value, WorksheetWindowOptions.ShowZeroValues);
            }
        }

        public VerticalPageBreakCollection VerticalPageBreaks
        {
            get
            {
                return this.verticalPageBreaks;
            }
        }

        public int Zoom
        {
            get
            {
                return this.zoom;
            }
            set
            {
                if ((value < 10) || (value > 400))
                {
                    throw new ArgumentOutOfRangeException("value", value, "Zoom must be in range from 10 to 400.");
                }
                this.zoom = value;
            }
        }
    }
}

